<?php
/**
 * Zend Framework (http://framework.zend.com/)
 *
 * @link      http://github.com/zendframework/ZendSkeletonApplication for the canonical source repository
 * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
 * @license   http://framework.zend.com/license/new-bsd New BSD License
 */

namespace Application;

use Zend\Mvc\ModuleRouteListener;
use Zend\Mvc\MvcEvent;
use Zend\Db\TableGateway\TableGateway;
use Zend\Db\ResultSet\ResultSet;
use Zend\ModuleManager\Feature\ServiceProviderInterface;
use Zend\ModuleManager\ModuleManager;

use Application\Service\ErrorHandling as ErrorHandlingService;

use Application\Service\FileService as FileService;
use Application\Service\Sitemap\SitemapService as SitemapService;
use Application\Service\Sitemap\url as Url;

use Zend\Log\Logger;
use Zend\Log\Writer\Stream as LogWriterStream;

use Zend\ModuleManager\Feature\AutoloaderProviderInterface;
use Zend\Authentication\Storage;
use Zend\Authentication\AuthenticationService;
use Zend\Authentication\Adapter\DbTable as DbTableAuthAdapter;

use Application\Model\SejourTable;
use Application\Model\Sejour;

use Application\Model\RechercheTable;
use Application\Model\Recherche;

use Application\Model\SejourDateTable;
use Application\Model\SejourDate;
use Application\Model\SejourDaybydayTable;
use Application\Model\SejourDaybyday;
use Application\Model\SejourFicheTable;
use Application\Model\SejourFiche;
use Application\Model\SejourImageTable;
use Application\Model\SejourImage;
use Application\Model\SejourCommentairesTable;
use Application\Model\SejourCommentaires;

use Application\Model\AgenceTable;
use Application\Model\Agence;
use Application\Model\UtilisateurTable;
use Application\Model\Utilisateur;
use Application\Model\AgenceUtilisateursTable;
use Application\Model\AgenceUtilisateurs;
use Application\Model\RoleTable;
use Application\Model\Role;
use Application\Model\ActivitesSejourTable;
use Application\Model\ActivitesSejour;
use Application\Model\TypesSejourTable;
use Application\Model\TypesSejour;
use Application\Model\PaysTable;
use Application\Model\Pays;
use Application\Model\RegionsTable;
use Application\Model\Regions;
use Application\Model\InvitationTable;
use Application\Model\Invitation;
use Application\Model\ContactTable;
use Application\Model\Contact;
use Application\Model\SitemapTable;
use Application\Model\Sitemap;
use Application\Model\InformationTable;
use Application\Model\Information;
use Application\Model\FiltreTable;
use Application\Model\Filtre;
use Application\Model\RechercheSejourTable;
use Application\Model\RechercheSejour;
use Application\Model\PaysRegionsTable;
use Application\Model\PaysRegions;
use Application\Model\ThematiquesTable;
use Application\Model\Thematiques;
use Application\Model\ThemesSejourTable;
use Application\Model\ThemesSejour;

class Module
{
    public function onBootstrap(MvcEvent $e)
    {
        $e->getApplication()->getServiceManager()->get('viewhelpermanager')->setFactory('routeHelper', function($sm) use ($e) {
        	$viewHelper = new View\Helper\RouteNamesHelper($e->getRouteMatch());
        	return $viewHelper;
        });

        $eventManager = $e->getApplication()->getEventManager();

        $eventManager->getSharedManager()->attach('Zend\Mvc\Controller\AbstractActionController', 'dispatch', function($e) {
        	$controller      = $e->getTarget();
        	$controllerClass = get_class($controller);
        	$moduleNamespace = substr($controllerClass, 0, strpos($controllerClass, '\\'));
        	$config          = $e->getApplication()->getServiceManager()->get('config');
        	if (isset($config['module_layouts'][$moduleNamespace])) {
        		$controller->layout($config['module_layouts'][$moduleNamespace]);
        	}
        }, 100);
        
        $eventManager->attach(MvcEvent::EVENT_DISPATCH, function($e) {
            $controller = $e->getTarget();
            if ($controller instanceof Controller\SitemapController) {   
                $controller->layout('layout/layoutsitemap.phtml');
            }   
        });

        /* logging */
		$eventManager->attach('dispatch.error', function($event){
        	$exception = $event->getResult()->exception;
			
        	if ($exception) {
        		$sm = $event->getApplication()->getServiceManager();
        		$service = $sm->get('Application\Service\ErrorHandling');
        		$service->logException($exception);
        	}
        });
        
        $moduleRouteListener = new ModuleRouteListener();
        $moduleRouteListener->attach($eventManager);

        $viewModel = $e->getApplication()->getMvcEvent()->getViewModel();

        $config = $e->getApplication()->getServiceManager()->get('config');
        $root_url = $config['root_url'];

        $viewModel->root_url = $root_url;
    }

    public function getConfig()
    {
        return include __DIR__ . '/config/module.config.php';
    }

    public function getAutoloaderConfig()
    {
        return array(
            'Zend\Loader\StandardAutoloader' => array(
                'namespaces' => array(
                    __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
                ),
            ),
        );
    }
    
	public function getServiceConfig() {
        return array(
        	'invokables' => array(
        		// 'FileService' => 'Application\Service\FileService',
        		'StringService' => 'Application\Service\StringService',
        		'MailService' => 'Application\Service\MailService',
        		'url' => 'Application\Service\Sitemap\url',        		
        		'DateService' => 'Application\Service\DateService',
        		'ImportSejourService' => 'Application\Service\ImportCsv\ImportSejourService',
        	),
        	'factories' => array(
        		'FileService' => function ($sl) {
	                $thumbnailer = $sl->get('WebinoImageThumb');

	                return new FileService( $thumbnailer );
	            },
	            'SitemapService' => function ($sl) {
	                $urlService = $sl->get('url');

	                return new SitemapService( new Url() );
	            },
				'Application\Model\AuthStorage' => function($sm){
					return new \Application\Model\AuthStorage('zf_tutorial');
				},
				'AuthService' => function($sm) {
					//My assumption, you've alredy set dbAdapter
					//and has users table with columns : user_name and pass_word
					//that password hashed with md5
					$dbAdapter           = $sm->get('Zend\Db\Adapter\Adapter');
					$dbTableAuthAdapter  = new DbTableAuthAdapter($dbAdapter,
							'Utilisateur','email','mdp');
					 
					$authService = new AuthenticationService();
					$authService->setAdapter($dbTableAuthAdapter);
					$authService->setStorage($sm->get('Application\Model\AuthStorage'));
				
					return $authService;
				},
				'Application\Service\ErrorHandling' =>  function($sm) {
	        		$logger = $sm->get('Zend\Log');
	        		$service = new ErrorHandlingService($logger);
	        		return $service;
	        	},
	        	'Zend\Log' => function ($sm) {
	        		$filename = 'log_' . date('F') . '.txt';
	        		$log = new Logger();
	        		$writer = new LogWriterStream('./data/logs/' . $filename);
	        		$log->addWriter($writer);
	        		
	        		return $log;
	        	},

				'Application\Model\SejourTable' =>  function($sm) {
					$tableGateway = $sm->get('SejourTableGateway');
					$authServiceGateway = $sm->get('AuthService');
					$FileService = $sm->get('FileService');
					$StringService = $sm->get('StringService');
					$ThemesSejourGateway = $sm->get('Application\Model\ThemesSejourTable');
	                $table = new SejourTable($tableGateway, $authServiceGateway, $FileService, $StringService, $ThemesSejourGateway);
	                return $table;
				},
		        'SejourTableGateway' => function ($sm) {
		        	$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
		        	$resultSetPrototype = new ResultSet();
		        	$resultSetPrototype->setArrayObjectPrototype(new Sejour());
		        	return new TableGateway('Sejour', $dbAdapter, null, $resultSetPrototype);
		        },

		        'Application\Model\RechercheTable' =>  function($sm) {
					$tableGateway = $sm->get('RechercheTableGateway');
					$RegionsTableGateway = $sm->get('Application\Model\RegionsTable');
					$PaysTableGateway = $sm->get('Application\Model\PaysTable');
					$ActivitesSejourTableGateway = $sm->get('Application\Model\ActivitesSejourTable');
					$ThematiquesTableGateway = $sm->get('Application\Model\ThematiquesTable');
					$StringService = $sm->get('StringService');
					$AgenceTableGateway = $sm->get('Application\Model\AgenceTable');
	                $table = new RechercheTable($tableGateway, $RegionsTableGateway, $PaysTableGateway, $ActivitesSejourTableGateway, $AgenceTableGateway, $ThematiquesTableGateway, $StringService);
	                return $table;
				},
		        'RechercheTableGateway' => function ($sm) {
		        	$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
		        	$resultSetPrototype = new ResultSet();
		        	$resultSetPrototype->setArrayObjectPrototype(new Recherche());
		        	return new TableGateway('Sejour', $dbAdapter, null, $resultSetPrototype);
		        },

		        'Application\Model\SejourDateTable' =>  function($sm) {
					$tableGateway = $sm->get('SejourDateTableGateway');
	                $table = new SejourDateTable($tableGateway);
	                return $table;
				},
		        'SejourDateTableGateway' => function ($sm) {
		        	$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
		        	$resultSetPrototype = new ResultSet();
		        	$resultSetPrototype->setArrayObjectPrototype(new SejourDate());
		        	return new TableGateway('Sejour_date', $dbAdapter, null, $resultSetPrototype);
		        },
		        'Application\Model\SejourDaybydayTable' =>  function($sm) {
					$tableGateway = $sm->get('SejourDaybydayTableGateway');
	                $table = new SejourDaybydayTable($tableGateway);
	                return $table;
				},
		        'SejourDaybydayTableGateway' => function ($sm) {
		        	$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
		        	$resultSetPrototype = new ResultSet();
		        	$resultSetPrototype->setArrayObjectPrototype(new SejourDaybyday());
		        	return new TableGateway('Sejour_daybyday', $dbAdapter, null, $resultSetPrototype);
		        },

		        'Application\Model\SejourCommentairesTable' =>  function($sm) {
					$tableGateway = $sm->get('SejourCommentairesTableGateway');
	                $table = new SejourCommentairesTable($tableGateway);
	                return $table;
				},
		        'SejourCommentairesTableGateway' => function ($sm) {
		        	$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
		        	$resultSetPrototype = new ResultSet();
		        	$resultSetPrototype->setArrayObjectPrototype(new SejourCommentaires());
		        	return new TableGateway('Sejour_commentaires', $dbAdapter, null, $resultSetPrototype);
		        },

		        'Application\Model\SejourFicheTable' =>  function($sm) {
					$tableGateway = $sm->get('SejourFicheTableGateway');
	                $table = new SejourFicheTable($tableGateway);
	                return $table;
				},
		        'SejourFicheTableGateway' => function ($sm) {
		        	$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
		        	$resultSetPrototype = new ResultSet();
		        	$resultSetPrototype->setArrayObjectPrototype(new SejourFiche());
		        	return new TableGateway('Sejour_fiche', $dbAdapter, null, $resultSetPrototype);
		        },

		        'Application\Model\SejourImageTable' =>  function($sm) {
					$tableGateway = $sm->get('SejourImageTableGateway');
	                $FileService = $sm->get('FileService');

	                $table = new SejourImageTable($tableGateway, $FileService);
	                return $table;
				},
		        'SejourImageTableGateway' => function ($sm) {
		        	$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
		        	$resultSetPrototype = new ResultSet();
		        	$resultSetPrototype->setArrayObjectPrototype(new SejourImage());
		        	return new TableGateway('Sejour_image', $dbAdapter, null, $resultSetPrototype);
		        },

		        'Application\Model\AgenceTable' =>  function($sm) {
		        	$tableGateway = $sm->get('AgenceTableGateway');
		        	$authServiceGateway = $sm->get('AuthService');
		        	$FileService = $sm->get('FileService');
		        	$table = new AgenceTable($tableGateway, $authServiceGateway, $FileService);
		        	return $table;
		        },
		        'AgenceTableGateway' => function ($sm) {
		        	$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
		        	$resultSetPrototype = new ResultSet();
		        	$resultSetPrototype->setArrayObjectPrototype(new Agence());
		        	return new TableGateway('Agence', $dbAdapter, null, $resultSetPrototype);
		        },
		        'Application\Model\UtilisateurTable' =>  function($sm) {
		        	$tableGateway = $sm->get('UtilisateurTableGateway');
		        	$authServiceGateway = $sm->get('AuthService');
		        	$table = new UtilisateurTable($tableGateway, $authServiceGateway);
		        	return $table;
		        },
		        'UtilisateurTableGateway' => function ($sm) {
		        	$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
		        	$resultSetPrototype = new ResultSet();
		        	$resultSetPrototype->setArrayObjectPrototype(new Utilisateur());
		        	return new TableGateway('Utilisateur', $dbAdapter, null, $resultSetPrototype);
		        },
		        'Application\Model\RoleTable' =>  function($sm) {
		        	$tableGateway = $sm->get('RoleTableGateway');
		        	$table = new RoleTable($tableGateway);
		        	return $table;
		        },
		        'RoleTableGateway' => function ($sm) {
		        	$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
		        	$authServiceGateway = $sm->get('AuthService');
		        	$resultSetPrototype = new ResultSet();
		        	$resultSetPrototype->setArrayObjectPrototype(new Role($authServiceGateway));
		        	return new TableGateway('Role', $dbAdapter, null, $resultSetPrototype);
		        },
		        'Application\Model\ActivitesSejourTable' =>  function($sm) {
		        	$tableGateway = $sm->get('ActivitesSejourTableGateway');
		        	$table = new ActivitesSejourTable($tableGateway);
		        	return $table;
		        },
		        'ActivitesSejourTableGateway' => function ($sm) {
		        	$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
		        	$resultSetPrototype = new ResultSet();
		        	$resultSetPrototype->setArrayObjectPrototype(new ActivitesSejour());
		        	return new TableGateway('ActivitesSejour', $dbAdapter, null, $resultSetPrototype);
		        },
		        'Application\Model\TypesSejourTable' =>  function($sm) {
		        	$tableGateway = $sm->get('TypesSejourTableGateway');
		        	$table = new TypesSejourTable($tableGateway);
		        	return $table;
		        },
		        'TypesSejourTableGateway' => function ($sm) {
		        	$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
		        	$resultSetPrototype = new ResultSet();
		        	$resultSetPrototype->setArrayObjectPrototype(new TypesSejour());
		        	return new TableGateway('TypesSejour', $dbAdapter, null, $resultSetPrototype);
		        },
		        'Application\Model\RegionsTable' =>  function($sm) {
		        	$tableGateway = $sm->get('RegionsTableGateway');
		        	$SejourTableGateway = $sm->get('Application\Model\SejourTable');
		        	$table = new RegionsTable($tableGateway, $SejourTableGateway);
		        	return $table;
		        },
		        'RegionsTableGateway' => function ($sm) {
		        	$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
		        	$resultSetPrototype = new ResultSet();
		        	$resultSetPrototype->setArrayObjectPrototype(new Regions());
		        	return new TableGateway('Regions', $dbAdapter, null, $resultSetPrototype);
		        },
		        'Application\Model\PaysTable' =>  function($sm) {
		        	$tableGateway = $sm->get('PaysTableGateway');
					$SejourTableGateway = $sm->get('Application\Model\SejourTable');		        	
		        	$table = new PaysTable($tableGateway, $SejourTableGateway);
		        	return $table;
		        },
		        'PaysTableGateway' => function ($sm) {
		        	$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
		        	$resultSetPrototype = new ResultSet();
		        	$resultSetPrototype->setArrayObjectPrototype(new Pays());
		        	return new TableGateway('Pays', $dbAdapter, null, $resultSetPrototype);
		        },
		        'Application\Model\InvitationTable' =>  function($sm) {
		        	$tableGateway = $sm->get('InvitationTableGateway');
		        	$table = new InvitationTable($tableGateway);
		        	return $table;
		        },
		        'InvitationTableGateway' => function ($sm) {
		        	$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
		        	$resultSetPrototype = new ResultSet();
		        	$resultSetPrototype->setArrayObjectPrototype(new Invitation());
		        	return new TableGateway('Invitation', $dbAdapter, null, $resultSetPrototype);
		        },
		        'Application\Model\ContactTable' =>  function($sm) {
		        	$tableGateway = $sm->get('ContactTableGateway');
		        	$table = new ContactTable($tableGateway);
		        	return $table;
		        },
		        'ContactTableGateway' => function ($sm) {
		        	$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
		        	$resultSetPrototype = new ResultSet();
		        	$resultSetPrototype->setArrayObjectPrototype(new Contact());
		        	return new TableGateway('Contact', $dbAdapter, null, $resultSetPrototype);
		        },
		        'Application\Model\SitemapTable' =>  function($sm) {
		        	$tableGateway = $sm->get('SitemapTableGateway');
		        	$SejourTableGateway = $sm->get('Application\Model\SejourTable');
		        	$table = new SitemapTable($tableGateway, $SejourTableGateway);
		        	return $table;
		        },
		        'SitemapTableGateway' => function ($sm) {
		        	$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
		        	$resultSetPrototype = new ResultSet();
		        	$resultSetPrototype->setArrayObjectPrototype(new Sitemap());
		        	return new TableGateway('Sitemap', $dbAdapter, null, $resultSetPrototype);
		        },
		        'Application\Model\InformationTable' =>  function($sm) {
		        	$tableGateway = $sm->get('InformationTableGateway');
		        	$table = new InformationTable($tableGateway);
		        	return $table;
		        },
		        'InformationTableGateway' => function ($sm) {
		        	$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
		        	$resultSetPrototype = new ResultSet();
		        	$resultSetPrototype->setArrayObjectPrototype(new Information());
		        	return new TableGateway('Information', $dbAdapter, null, $resultSetPrototype);
		        },
		        'Application\Model\FiltreTable' =>  function($sm) {
		        	$tableGateway = $sm->get('FiltreTableGateway');
		        	$RechercheSejourTableGateway = $sm->get('Application\Model\RechercheSejourTable');
		        	$table = new FiltreTable($tableGateway, $RechercheSejourTableGateway);
		        	return $table;
		        },
		        'FiltreTableGateway' => function ($sm) {
		        	$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
		        	$resultSetPrototype = new ResultSet();
		        	$resultSetPrototype->setArrayObjectPrototype(new Filtre());
		        	return new TableGateway('Filtre', $dbAdapter, null, $resultSetPrototype);
		        },
		        'Application\Model\RechercheSejourTable' =>  function($sm) {
		        	$tableGateway = $sm->get('RechercheSejourTableGateway');
					$ThemesSejourTableGateway = $sm->get('Application\Model\ThemesSejourTable');
					$RegionsTableGateway = $sm->get('Application\Model\RegionsTable');
		        	$StringService = $sm->get('StringService');
		        	$table = new RechercheSejourTable($tableGateway, $ThemesSejourTableGateway, $RegionsTableGateway, $StringService);
		        	return $table;
		        },
		        'RechercheSejourTableGateway' => function ($sm) {
		        	$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
		        	$resultSetPrototype = new ResultSet();
		        	$resultSetPrototype->setArrayObjectPrototype(new RechercheSejour());
		        	return new TableGateway('RechercheSejour', $dbAdapter, null, $resultSetPrototype);
		        },
		        'Application\Model\PaysRegionsTable' =>  function($sm) {
		        	$tableGateway = $sm->get('PaysTableGateway');
					$SejourTableGateway = $sm->get('Application\Model\SejourTable');
					$RegionsTableGateway = $sm->get('Application\Model\RegionsTable');
		        	$table = new PaysRegionsTable($tableGateway, $SejourTableGateway, $RegionsTableGateway);
		        	return $table;
		        },
		        'PaysRegionsTableGateway' => function ($sm) {
		        	$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
		        	$resultSetPrototype = new ResultSet();
		        	$resultSetPrototype->setArrayObjectPrototype(new PaysRegions());
		        	return new TableGateway('PaysRegions', $dbAdapter, null, $resultSetPrototype);
		        },
		        'Application\Model\ThematiquesTable' =>  function($sm) {
		        	$tableGateway = $sm->get('ThematiquesTableGateway');
		        	$table = new ThematiquesTable($tableGateway);
		        	return $table;
		        },
		        'ThematiquesTableGateway' => function ($sm) {
		        	$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
		        	$resultSetPrototype = new ResultSet();
		        	$resultSetPrototype->setArrayObjectPrototype(new Thematiques());
		        	return new TableGateway('Thematiques', $dbAdapter, null, $resultSetPrototype);
		        },
		        'Application\Model\ThemesSejourTable' =>  function($sm) {
		        	$tableGateway = $sm->get('ThemesSejourTableGateway');
		        	$table = new ThemesSejourTable($tableGateway);
		        	return $table;
		        },
		        'ThemesSejourTableGateway' => function ($sm) {
		        	$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
		        	$resultSetPrototype = new ResultSet();
		        	$resultSetPrototype->setArrayObjectPrototype(new ThemesSejour());
		        	return new TableGateway('ThemesSejour', $dbAdapter, null, $resultSetPrototype);
		        },
        ), );
    }
}
